<template>
  <div class="app-container">
    <!-- 搜索工作栏 -->
    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="流程名" prop="name">
        <el-input v-model="queryParams.name" placeholder="请输入流程名" clearable size="small" @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item label="所属流程" prop="processDefinitionId">
        <el-input v-model="queryParams.processDefinitionId" placeholder="请输入流程定义的编号" clearable size="small" @keyup.enter.native="handleQuery" />
      </el-form-item>
      <el-form-item label="流程分类" prop="category">
        <el-select v-model="queryParams.category" placeholder="请选择流程分类" clearable size="small">
          <el-option v-for="dict in dict.type.bpm_model_category" :key="dict.value" :label="dict.label" :value="dict.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="提交时间">
        <el-date-picker v-model="dateRangeCreateTime" size="small" style="width: 240px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" />
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
          <el-option v-for="dict in dict.type.bpm_process_instance_status" :key="dict.value" :label="dict.label" :value="dict.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="结果" prop="result">
        <el-select v-model="queryParams.result" placeholder="请选择流结果" clearable size="small">
          <el-option v-for="dict in dict.type.bpm_process_instance_result" :key="dict.value" :label="dict.label" :value="dict.value" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <!-- 操作工具栏 -->
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['bpm:process-instance:query']">发起流程</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <!-- 列表 -->
    <el-table v-loading="loading" :data="list">
      <!-- <el-table-column label="编号" align="center" prop="id" width="320" /> -->
      <el-table-column label="流程名" align="center" prop="name" />
      <el-table-column label="流程分类" align="center" prop="category">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.bpm_model_category" :value="scope.row.category" />
        </template>
      </el-table-column>
      <el-table-column label="当前审批任务" align="center" prop="tasks">
        <template slot-scope="scope">
          <el-button v-for="task in scope.row.tasks" :key="task.id" type="text" @click="handleXmlDetail(scope.row.id)">
            <span v-if="task.name != ''">{{ task.name }}</span>
            <span v-else>已完成,暂无任务</span>
          </el-button>
        </template>
      </el-table-column>
      <el-table-column label="状态" align="center" prop="status">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.bpm_process_instance_status" :value="scope.row.status" />
        </template>
      </el-table-column>
      <el-table-column label="结果" align="center" prop="result">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.bpm_process_instance_result" :value="scope.row.result" />
        </template>
      </el-table-column>
      <el-table-column label="提交时间" align="center" prop="createTime" width="180">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.createTime) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="结束时间" align="center" prop="createTime" width="180">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.endTime) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" min-width="150">
        <template slot-scope="scope">
          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleExamine(scope.row)" v-if="scope.row.result === 1" v-hasPermi="['bpm:process-instance:examine']">干预审批</el-button>
          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleDetail(scope.row)" v-hasPermi="['bpm:process-instance:query']">详情</el-button>
          <el-button type="text" size="small" icon="el-icon-picture-outline" @click="handleXmlDetail(scope.row.id)">流程图</el-button>
          <el-button type="text" size="small" icon="el-icon-delete" v-if="scope.row.result === 1" v-hasPermi="['bpm:process-instance:cancel']" @click="handleCancel(scope.row)">取消</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页组件 -->
    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" @pagination="getList" />

    <!-- 流程模型图的预览 -->
    <el-dialog title="干预审批" :visible.sync="showBpmnOpen" width="60%" append-to-body>
      <el-form label-width="100px">
        <el-form-item label="审批建议" prop="comment">
          <el-input type="textarea" v-model="comment" placeholder="请输入审批建议" />
        </el-form-item>
      </el-form>
      <div style="margin-left: 10%; margin-bottom: 20px; font-size: 14px">
        <el-button icon="el-icon-edit-outline" type="success" round plain size="mini" @click="handleAudit(true)">通过</el-button>
        <el-button icon="el-icon-circle-close" type="danger" round plain size="mini" @click="handleAudit(false)">不通过</el-button>
        <el-button icon="el-icon-edit-outline" type="primary" round plain size="mini" @click="handleUpdateAssignee()">转办</el-button>
        <el-button icon="el-icon-edit-outline" type="primary" round plain size="mini" @click="handleDelegate()">委派</el-button>
        <el-button icon="el-icon-refresh-left" type="warning" round plain size="mini" @click="handleBack()">退回</el-button>
      </div>
    </el-dialog>

    <el-dialog title="流程图" :visible.sync="openXml" width="65%" append-to-body>
      <!-- 高亮流程图 -->
      <el-card class="box-card">
        <div slot="header" class="clearfix">
          <my-process-viewer key="designer" v-model="bpmnXML" v-bind="bpmnControlForm" :activityData="activityList" :processInstanceData="processInstanceInfo" :taskData="tasks" style="height: 500px" />
        </div>
      </el-card>
    </el-dialog>
  </div>
</template>

<script>
import { getActivityList } from '@/api/bpm/activity'
import { getProcessDefinitionBpmnXML } from '@/api/bpm/definition'
import { createInprocessInstanceInfo, getProcessInstance } from '@/api/bpm/processInstance'
import { getMyProcessInstancePage, cancelProcessInstance } from '@/api/bpm/processInstance'
import { approveTask, getTaskListByProcessInstanceId, rejectTask, updateTaskAssignee, approveTaskIntervene } from '@/api/bpm/task'
import { flatten } from 'min-dash'
export default {
  name: 'ProcessInstance',
  dicts: ['bpm_model_category', 'bpm_process_instance_result', 'bpm_process_instance_status'],
  components: {},
  data() {
    return {
      bpmnControlForm: {
        prefix: 'activiti'
      },
      openXml: false,
      bpmnXML: null,
      activityList: [],
      processInstanceInfo: {},
      runningTasks: [],
      tasks: [],
      showBpmnOpen: false,
      newId: '',
      comment: '',

      // 遮罩层
      loading: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 工作流的流程实例的拓展列表
      list: [],
      // 是否显示弹出层
      dateRangeCreateTime: [],
      // 查询参数
      queryParams: {
        pageNo: 1,
        pageSize: 10,
        name: null,
        processDefinitionId: null,
        category: null,
        status: null,
        result: null
      }
    }
  },
  created() {
    this.getList()
  },
  methods: {
    handleXmlDetail(id) {
      this.getTaskInfo(id)
      getProcessInstance(id).then((response) => {
        if (!response.data) {
          this.$message.error('查询不到流程信息！')
          return
        }
        // 设置流程信息
        this.processInstanceInfo = response.data

        // 加载流程图
        getProcessDefinitionBpmnXML(this.processInstanceInfo.processDefinition.id).then((response) => {
          this.bpmnXML = response.msg
        })
        // 加载活动列表
        getActivityList({
          processInstanceId: this.processInstanceInfo.id
        }).then((response) => {
          this.activityList = response.data
        })

        // 取消加载中
        this.processInstanceLoading = false
      })
      this.openXml = true
    },
    getTaskInfo(id) {
      getTaskListByProcessInstanceId(id).then((response) => {
        // 审批记录

        this.tasks = response.data
        // 排序，将未完成的排在前面，已完成的排在后面；
        this.tasks.sort((a, b) => {
          // 有已完成的情况，按照完成时间倒序
          if (a.endTime && b.endTime) {
            return b.endTime - a.endTime
          } else if (a.endTime) {
            return 1
          } else if (b.endTime) {
            return -1
            // 都是未完成，按照创建时间倒序
          } else {
            return b.createTime - a.createTime
          }
        })

        var taskQu = JSON.parse(JSON.stringify(this.tasks))
        this.runningTasks = []

        if (taskQu.length < 1) {
          this.showBpmnOpen = false
          this.$modal.msgError('很抱歉，没有找到对应的任务流程')
          return
        }
        taskQu.forEach((task) => {
          if (task.result !== 1) {
            // 只有待处理才需要
            return
          }
          this.runningTasks.push({ ...task })
        })
      })
    },

    /** 处理审批退回的操作 */
    handleDelegate() {
      this.$modal.msgError('暂不支持【委派】功能，可以使用【转派】替代！')
    },
    /** 处理审批退回的操作 */
    handleBack() {
      this.$modal.msgError('暂不支持【退回】功能！')
    },
    /** 处理审批通过和不通过的操作 */
    handleAudit(pass) {
      const data = {
        id: this.runningTasks[0].id,
        comment: this.comment
      }
      if (pass) {
        approveTaskIntervene(data).then((response) => {
          this.showBpmnOpen = false
          this.$modal.msgSuccess('审批通过成功！')
          this.getList()
        })
      } else {
        rejectTask(data).then((response) => {
          this.$modal.msgSuccess('审批不通过成功！')
        })
      }
    },
    /** 处理转派审批人 */
    handleUpdateAssignee() {
      // 设置表单
      this.resetUpdateAssigneeForm()
      // 设置为打开
      this.updateAssignee.open = true
    },

    handleExamine(row) {
      this.newId = row.id
      this.showBpmnOpen = true
      this.getTaskInfo(row.id)
    },
    /** 查询列表 */
    getList() {
      this.loading = true
      // 处理查询参数
      let params = { ...this.queryParams }
      this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime')
      // 执行查询
      getMyProcessInstancePage(params).then((response) => {
        this.list = response.data.list
        this.total = response.data.total
        this.loading = false
      })
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNo = 1
      this.getList()
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.dateRangeCreateTime = []
      this.resetForm('queryForm')
      this.handleQuery()
    },
    /** 新增按钮操作 **/
    handleAdd() {
      this.$router.push({ path: '/activiti/work/start/process' })
    },
    /** 取消按钮操作 */
    handleCancel(row) {
      const id = row.id
      this.$prompt('请输入取消原因？', '取消流程', {
        type: 'warning',
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputPattern: /^[\s\S]*.*[^\s][\s\S]*$/, // 判断非空，且非空格
        inputErrorMessage: '取消原因不能为空'
      })
        .then(({ value }) => {
          return cancelProcessInstance(id, value)
        })
        .then(() => {
          this.getList()
          this.$modal.msgSuccess('取消成功')
        })
    },
    /** 处理详情按钮 */
    handleDetail(row) {
      this.$router.push({ path: '/activiti/process/detail', query: { id: row.id } })
    }
  }
}
</script>
